home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / terms / tipx / libacu / telebit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-11  |  7.9 KB  |  360 lines

  1. /*
  2.  * Dialer support for Telebit Trailblazer Plus modem.
  3.  */
  4.  
  5. #ifndef lint
  6. static char *RCSid = "$Header: telebit.c,v 1.13 88/05/25 19:48:06 rayan Exp $";
  7. #endif
  8.  
  9. #undef DEBUG 1
  10.  
  11. #ifdef    DEBUG
  12. int debug = 1;
  13. #define STATIC
  14. #else
  15. #define STATIC static
  16. #endif
  17.  
  18. #include "tip.h"
  19. #include <sys/time.h>
  20.  
  21. /*
  22.  * The following is the Telebit register setup used here with this code, with
  23.  * the TB+ attached to a fixed-speed interface on a remote terminal server.
  24.  * When attaching to a computer the appropriate register should be set so
  25.  * the TB+ interface speed matches the connect baud rate.
  26.  *
  27. E0 F1 M1 Q1 P V1 X1     Version BA4.00
  28. S00=001 S01=000 S02=043 S03=013 S04=010 S05=008 S06=002 S07=040 S08=002 S09=006
  29. S10=007 S11=070 S12=050 
  30. S45=255 S47=004 S48=000 S49=000
  31. S50=000 S51=005 S52=002 S53=004 S54=003 S55=000 S56=017 S57=019 S58=000 S59=000
  32. S60=000 S61=000 S62=003 S63=001 S64=000 S65=000 S66=000 S67=000 S68=255 
  33. S90=000 S91=000 S92=000 S95=000 
  34. S100=000 S101=000 S102=000 S104=000 
  35. S110=001 S111=030 S112=001 
  36. S121=000 
  37.  *
  38.  */
  39.  
  40.     /* commands */
  41. STATIC char    NAME[] =        "telebit";
  42. STATIC char    WARMUP[] =        "\rat\r";
  43. STATIC char    RESULT_CODES[] =    "\ratq0\r";
  44. STATIC char    DONT_ANSWER[] =        "\rats0=0\r";
  45. STATIC char    IGN_ESCAPE[] =        "\rats55=3\r";
  46. STATIC char    CODES_4[] =        "\ratx1\r";
  47. STATIC char    DIAL_PREFIX[] =        "\ratdt";
  48.  
  49.     /* result codes */;
  50. STATIC char    MDM_OK[] =        "\r\nOK\r\n";
  51. STATIC char    RING[] =        "\r\nRING\r\n";
  52. STATIC char    RRING[] =        "\r\nRRING\r\n";
  53. STATIC char    NO_CARRIER[] =        "\r\nNO CARRIER\r\n";
  54. STATIC char    ERROR[] =        "\r\nERROR\r\n";
  55. STATIC char    CONNECT[] =        "\r\nCONNECT 300\r\n";
  56. STATIC char    CONNECT_1200[] =    "\r\nCONNECT 1200\r\n";
  57. STATIC char    CONNECT_2400[] =    "\r\nCONNECT 2400\r\n";
  58. STATIC char    CONNECT_FAST[] =    "\r\nCONNECT FAST\r\n";
  59. STATIC char    NO_DIALTONE[] =        "\r\nNO DIALTONE\r\n";
  60. STATIC char    NO_ANSWER[] =        "\r\nNO ANSWER\r\n";
  61. STATIC char    BUSY[] =        "\r\nBUSY\r\n";
  62.  
  63. STATIC char    *notbcon[] =    {    BUSY,
  64.                     NO_DIALTONE,
  65.                     NO_ANSWER,
  66.                     ERROR,
  67.                     RING,
  68.                     NO_CARRIER,
  69.                     0
  70.                 };
  71.  
  72. /* The baudrate starts at 300, and doubles for next element of array */
  73. STATIC char    *tbcon[] =    {    CONNECT,
  74.                     "ignore",
  75.                     CONNECT_1200,
  76.                     CONNECT_2400,
  77.                     "ignore",
  78.                     "ignore",
  79.                     CONNECT_FAST,
  80.                     0
  81.                 };
  82. #ifdef    USG
  83. STATIC struct termio termio;        /* needed on USG to set HUPCL */
  84. #endif    /* USG */
  85.  
  86. #define    CMD_DELAY    5    /* number of seconds to wait for response
  87.                     while in command mode */
  88. #define DIAL_DELAY    120    /* number of seconds to wait for response
  89.                     after sending dial string */
  90. #define    MAXSTR    100
  91.  
  92. static jmp_buf    jmpbuf;
  93.  
  94. int     tbread(), tbwrite();
  95.  
  96. tb_dialer(num, acu)
  97. register char    *num;
  98. char    *acu;
  99. {
  100.     int    ret;
  101.     int    i, j;
  102.     char    buf1[MAXSTR], buf2[MAXSTR], buf3[MAXSTR];
  103. #ifdef ACULOG
  104.     char    line[MAXSTR];
  105. #endif
  106.  
  107.     /*
  108.      * wake up the modem if it's listening...
  109.      */
  110.     if (boolean(value(VERBOSE)))
  111.         printf("diddling dialer...");
  112. #ifdef DEBUG
  113.     if (debug)
  114.         fprintf(stderr, "BR=%d\n", BR);
  115. #endif
  116.  
  117.     sleep(1);    /* Give modem time to settle down after reset */
  118.     if ((!tbset(RESULT_CODES, buf1, num, "is naughty")
  119.              && !tbset(RESULT_CODES, buf1, num, "not listening"))
  120.         || !tbset(DONT_ANSWER, buf1, num, "auto-answer not turned off")
  121.         || !tbset(IGN_ESCAPE, buf1, num, "escape code not turned off")
  122.         || !tbset(CODES_4, buf1, num, "result codes not set"))
  123.         return 0;
  124.  
  125.     /* insurance ? */
  126. #ifdef    USG
  127.     if (ioctl(FD, TCGETA, &termio) < 0)
  128.         perror("tip: TCGETA ioctl");
  129.     termio.c_cflag |= HUPCL;
  130.     if (ioctl(FD, TCSETA, &termio) < 0)
  131.         perror("tip: TCSETA ioctl");
  132. #else    /* USG */
  133.     if (ioctl(FD, TIOCHPCL, 0) < 0)
  134.         perror("tip: TIOCHPCL ioctl");
  135. #endif    /* USG */
  136.  
  137.     buf2[0] = '\0';
  138.     for (i = 0, j = 300; tbcon[i] != (char *)0; i++, j*=2) {
  139.         if (BR == j) {
  140.             strcpy(buf2, tbcon[i]);
  141.             break;
  142.         }
  143.     }
  144.     if (buf2[0] == '\0') {
  145.         sprintf(buf2, "unsupported baud rate (%d)", BR);
  146.         goto error;
  147.     }
  148.  
  149.     /* Is it safe to just say ATD and let the options setting rule? */
  150.     tbwrite(DIAL_PREFIX);
  151.     tbwrite(num);
  152.     tbwrite("\r");
  153.     if (boolean(value(VERBOSE)))
  154.         printf(" dialing... ");
  155.     do {
  156.         if (ret = tbread(buf1, DIAL_DELAY, (u_int) strlen(buf2)) == 0) {
  157.             strcpy(buf2, "TIMEOUT on dial");
  158.             goto error;
  159.         }
  160.         if (ret == -1) {
  161.             strcpy(buf2, "ioctl failed");
  162.             goto error;
  163.         }
  164.     } while (strncmp(buf1, RRING, strlen(RRING)) == 0
  165.         && (!boolean(value(VERBOSE)) || (printf("rrring... "), 1)));
  166.     if (strncmp(buf1, buf2, strlen(buf2)) != 0) {
  167.         for (i = 0, j = 300; tbcon[i] != (char *)0; i++, j *= 2) {
  168.             if (!strncmp(buf1, tbcon[i], strlen(tbcon[i]))) {
  169.                 /* This should never fail */
  170.                 if ((i = speed(j)) != NULL) {
  171.                     BR = j;
  172.                     ttysetup(i);
  173.                 } else {
  174.                     printf("speed(%d) failed\n", j);
  175.                     return 0;
  176.                 }
  177.                 goto ok;
  178.             }
  179.         }
  180.         for (i = 0; notbcon[i] != (char *)0; i++) {
  181.             if (!strncmp(buf1, notbcon[i], strlen(notbcon[i]))){
  182.                 char    *bp, *cp;
  183.                 for (bp = buf2, cp = notbcon[i]; *cp; cp++) {
  184.                     if (*cp != '\r' && *cp != '\n')
  185.                         *bp++ = *cp;
  186.                 }
  187.                 *bp = '\0';
  188.                 goto error;
  189.             }
  190.         }
  191.         (void) strcpy(buf2, "UNKNOWN ERROR [");
  192.         (void) strcat(buf2, buf1);
  193.         (void) strcat(buf2, "]");
  194. error:
  195.         printf("dial failed (%s)\n", buf2);
  196.         sprintf(buf3, "dial failed (%s)", buf2);
  197. #ifdef ACULOG
  198.         logent(value(HOST), num, NAME, buf3);
  199. #endif
  200.         return 0;
  201.     }
  202. ok:
  203.     if (boolean(value(VERBOSE)))
  204.         printf("(%d baud) ", BR);
  205.     i = 2;
  206. #ifdef    USG
  207.     if (ioctl(FD, TCFLSH, i) < 0)
  208.         perror("tip: TCFLSH ioctl");
  209. #else    /* USG */
  210.     if (ioctl(FD, TIOCFLUSH, &i) < 0)
  211.         perror("tip: TIOCFLUSH ioctl");
  212. #endif    /* USG */
  213.     return 1;
  214. }
  215.  
  216.  
  217. tb_disconnect()
  218. {
  219. #ifdef    USG
  220.     if (ioctl(FD, TCGETA, &termio) < 0)
  221.         perror("tip: TCGETA ioctl");
  222.     termio.c_cflag &= (CBAUD & B0);
  223.     if (ioctl(FD, TCSETA, &termio) < 0)
  224.         perror("tip: TCSETA ioctl");
  225.     sleep(2);
  226. #endif    /* USG */
  227.     (void) close(FD);
  228. }
  229.  
  230.  
  231. tb_abort()
  232. {
  233.     tb_disconnect();
  234. }
  235.  
  236. STATIC
  237. tbwrite(cp)
  238. register char    *cp;
  239. {
  240.     struct timeval t;
  241.  
  242.     for (; *cp != '\0' ; cp++) {
  243.         if (write(FD, cp, 1) != 1) {
  244.             perror("tip: tbwrite: write error");
  245.             return;
  246.         }
  247. #ifdef    DEBUG
  248.         if (debug) {
  249.             fprintf(stderr, "written '%c'\n", *cp);
  250.         }
  251. #endif
  252.         t.tv_sec = 0;
  253.         t.tv_usec = (20 * 10 * 1000000)/BR;
  254.         (void) select(32, 0, 0, 0, &t);
  255.     }
  256. }
  257.  
  258. STATIC
  259. tbread(buf, timeout, max)
  260. register char    *buf;
  261. unsigned int timeout, max;
  262. {
  263.     int    alarmtr();
  264.     struct timeval t;
  265.     register char    *rp;
  266.     unsigned int numread, numprev = 0, numpndg = 0;
  267.     unsigned int toread;
  268.  
  269. #ifdef    DEBUG
  270.     if (debug)
  271.         fprintf(stderr, "\n---------\nentering tbread(): timeout is: %d, max is: %d\n", timeout, max);
  272. #endif
  273.     rp = buf;
  274.     *rp = '\0';
  275.     (void) signal(SIGALRM, alarmtr);
  276.     if (setjmp(jmpbuf)) {
  277.         *rp = '\0';
  278.         return 0;
  279.     }
  280.     (void) alarm(timeout);
  281.         /* wait till modem says something or until timeout */
  282.     while (numpndg == 0 || numpndg != numprev) {
  283.         numprev = numpndg;
  284.         if (ioctl(FD, FIONREAD, &numpndg) == -1) {
  285.             perror("tip: FIONREAD ioctl");
  286.             return -1;
  287.         }
  288.         t.tv_sec = 0;
  289.         t.tv_usec = (100 * 10 * 1000000)/BR;
  290.         (void) select(32, 0, 0, 0, &t);
  291.     }
  292.     (void) alarm(0);
  293. #ifdef    DEBUG
  294.     if (debug)
  295.         fprintf(stderr, "number of chars waiting is: %d\n", numpndg);
  296. #endif
  297.     toread = ((numpndg > max) ? max : numpndg);
  298.       if ((numread = read(FD, rp, toread)) < toread)
  299.         perror("read error");
  300. #ifdef    DEBUG
  301.     if (debug) {
  302.         int i; char *p;
  303.         fprintf(stderr, "read %d chars:", numread);
  304.         for (i=0, p=rp; i<numread; i++, p++)
  305.             fprintf(stderr, "%0.2x ", *p);
  306.         fprintf(stderr, "\n");
  307.         fflush(stderr);
  308.     }
  309. #endif
  310.     rp += numread;
  311.     *rp = '\0';
  312. #ifdef    DEBUG
  313.     if (debug) {
  314.         fprintf(stderr, "\nbuf contains: ->%s<-\n", buf);
  315.         fprintf(stderr, "leaving tbread()\n-----------\n");
  316.         fflush(stderr);
  317.     }
  318. #endif
  319.     return 1;
  320. }
  321.  
  322.  
  323. STATIC
  324. accept(baudrate)
  325. int    baudrate;
  326. {
  327.     int i;
  328.  
  329.     BR = baudrate;
  330.     if ((i = speed(baudrate)) != NULL)
  331.         ttysetup(i);
  332. }
  333.  
  334.  
  335. STATIC
  336. alarmtr()
  337. {
  338. #ifdef    DEBUG
  339.     if (debug)
  340.         fprintf(stderr, "alarm went off!\n");
  341. #endif
  342.     longjmp(jmpbuf, 1);
  343. }
  344.  
  345. STATIC int
  346. tbset(tosend, buf, num, errmsg)
  347. char    *tosend, *buf, *num, *errmsg;
  348. {
  349.     tbwrite(tosend);
  350.     tbread(buf, CMD_DELAY, (u_int) (sizeof MDM_OK) - 1);
  351.     if (strncmp(buf, MDM_OK, (sizeof MDM_OK) - 1) != 0) {
  352.         printf(" %s modem %s\n", NAME, errmsg);
  353. #ifdef ACULOG
  354.         logent(value(HOST), num, NAME, errmsg);
  355. #endif
  356.         return 0;
  357.     }
  358.     return 1;
  359. }
  360.